 <template>
  <div class="validate-input-container pb-3">
    <input
      type="email"
      class="form-control"
      :value="InputRef.val"
      @blur="validateInput"
      @input="updataValue"
      v-bind="$attrs"
    />
    <div
      id="emailHelp"
      class="form-text"
      style="color: red"
      v-if="InputRef.error"
    >
      {{ InputRef.message }}
    </div>
  </div>
</template>

 <script lang="ts">
import { defineComponent, PropType, reactive, onMounted } from 'vue';
import { emitter } from './ValidateForm.vue';
const mailReg = /^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/;
interface RuleProp {
  type: 'required' | 'mail';
  message: string;
}
export type RuleProps = RuleProp[];
export default defineComponent({
  name: 'ValidateInput',
  props: {
    rules: {
      type: Array as PropType<RuleProps>,
      required: false,
    },
    modelValue: String,
  },
  inheritAttrs: false,
  setup(props, context) {
    const InputRef = reactive({
      val: props.modelValue || '',
      error: false,
      message: '',
    });
    const updataValue = (e: KeyboardEvent) => {
      const targetValue = (e.target as HTMLInputElement).value;
      InputRef.val = targetValue;
      context.emit('update:modelValue', targetValue);
    };
    const validateInput = () => {
      if (props.rules) {
        const allPassed = props.rules.every((rule) => {
          let passed = true;
          InputRef.message = rule.message;
          switch (rule.type) {
            case 'required':
              passed = InputRef.val !== '';
              break;
            case 'mail':
              passed = mailReg.test(InputRef.val);
              break;
            default:
              break;
          }
          return passed;
        });
        InputRef.error = !allPassed;
        return allPassed;
      }
      return true;
    };
    onMounted(() => {
      emitter.emit('form-item-created', validateInput);
    });
    return {
      InputRef,
      validateInput,
      updataValue,
    };
  },
});
</script>
